﻿using System;
using System.Collections.Generic;
using System.Text;

namespace WFL.Threading
{
    public class BatchInstance
    {
        private readonly object _lock = new object();

        public Guid Id
        {
            get;
            private set;
        }

        public BatchInstanceState State
        {
            get;
            internal set;
        }

        public Batch Batch
        {
            get;
            private set;
        }

        public BatchThread Thread
        {
            get;
            internal set;
        }

        public int ThreadId
        {
            get
            {
                if (Thread == null)
                {
                    return 0;
                }
                else
                {
                    return Thread.Id;
                }
            }
        }

        public BatchRuntime Runtime
        {
            get;
            internal set;
        }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime
        {
            get;
            internal set;
        }

        /// <summary>
        /// 进入等待调度队列的时间
        /// </summary>
        public DateTime WaitTime
        {
            get;
            internal set;
        }

        /// <summary>
        /// 开始执行时间
        /// </summary>
        public DateTime StartTime
        {
            get;
            internal set;
        }

        /// <summary>
        /// 结束执行时间
        /// </summary>
        public DateTime EndTime
        {
            get;
            internal set;
        }

        /// <summary>
        /// 启动任务实例时提供的数据
        /// </summary>
        public object ExecuteData
        {
            get;
            private set;
        }

        /// <summary>
        /// 取消任务实例时提供的数据
        /// </summary>
        public object CancelData
        {
            get;
            private set;
        }

        /// <summary>
        /// 中间过程数据，通常用于报告进度
        /// </summary>
        public object TempData
        {
            get;
            internal set;
        }

        /// <summary>
        /// 结果数据
        /// </summary>
        public object ResultData
        {
            get;
            internal set;
        }

        /// <summary>
        /// 异常数据
        /// </summary>
        public Exception Exception
        {
            get;
            internal set;
        }

        internal BatchInstance(Batch batch)
        {
            if (batch == null)
            {
                throw new ArgumentNullException("batch");
            }
            Id = Guid.NewGuid();
            Batch = batch;
            CreateTime = DateTime.Now;
        }

        public void Execute(object data)
        {
            lock(_lock)
            {
                if (State != BatchInstanceState.Initialized)
                {
                    return;
                }
                ExecuteData = data;
                Runtime.Execute(this);
            }
        }

        public void Cancel(object data)
        {
            lock(_lock)
            {
                if (State == BatchInstanceState.Cancelled
                    || State == BatchInstanceState.Exception
                    || State == BatchInstanceState.Succeeded)
                {
                    return;
                }
                CancelData = data;
                if (State == BatchInstanceState.Initialized)
                {
                    State = BatchInstanceState.Cancelled;
                    EndTime = DateTime.Now;
                    Batch.InstanceStateChange(this);
                    return;
                }
                Runtime.Cancel(this);
            }
        }
    }
}
